<template>
  <div>
    <el-card>
      <el-form :inline="true" class="user1">
        <el-form-item label="用户名：">
          <el-input
            v-model="keyword"
            placeholder="请输入搜索的用户名"
          ></el-input>
        </el-form-item>
        <el-form-item>
          <el-button
            type="primary"
            size="default"
            style="background-color: violet; width: 50px"
            :disabled="keyword ? false : true"
            @click="search"
          >
            搜索
          </el-button>
          <el-button
            type="primary"
            size="default"
            style="background-color: violet; width: 50px"
            @click="reset"
          >
            重置
          </el-button>
        </el-form-item>
      </el-form>
    </el-card>
    <el-card style="margin: 10px 0">
      <el-form>
        <el-button
          type="info"
          size="default"
          style="background-color: violet; width: 70px"
          @click="addUser"
        >
          添加用户
        </el-button>
        <el-button
          type="info"
          size="default"
          style="background-color: violet; width: 70px"
          :disabled="selecIdArr.length > 1 ? false : true"
          @click="deleteSelectUser"
        >
          批量删除
        </el-button>
      </el-form>
      <!-- table表格 -->
      <!-- @selection-change="selectChange" 选中/改变某一表格项时会触发此事件 -->
      <el-table
        border
        style="margin: 10px 0"
        :data="userArr"
        @selection-change="selectChange"
      >
        <el-table-column type="selection"></el-table-column>
        <el-table-column
          label="#"
          align="center"
          type="index"
        ></el-table-column>
        <el-table-column label="ID" align="center" prop="id"></el-table-column>
        <el-table-column
          label="用户名字"
          show-overflow-tooltip
          align="center"
          prop="username"
        ></el-table-column>
        <el-table-column
          label="用户名称"
          show-overflow-tooltip
          align="center"
          prop="name"
        ></el-table-column>
        <el-table-column
          label="用户角色"
          show-overflow-tooltip
          align="center"
          prop="roleName"
        ></el-table-column>
        <el-table-column
          label="创建时间"
          show-overflow-tooltip
          align="center"
          prop="createTime"
        ></el-table-column>
        <el-table-column
          label="更新时间"
          show-overflow-tooltip
          align="center"
          prop="updataTime"
        ></el-table-column>
        <el-table-column label="操作" align="center" width="260px">
          <template #="{ row, $index }">
            <el-button
              type="primary"
              size="small"
              icon="User"
              style="background-color: violet; width: 80px"
              @click="setRole(row)"
            >
              分配角色
            </el-button>
            <el-button
              type="primary"
              size="small"
              icon="Edit"
              style="background-color: violet; width: 50px"
              @click="updateUser(row)"
            >
              编辑
            </el-button>
            <!-- 气泡确认框 -->
            <el-popconfirm
              :title="`你确定要删除${row.name}吗？`"
              @confirm="deleteUser(row.id)"
            >
              <template #reference>
                <el-button
                  type="primary"
                  size="small"
                  icon="Delete"
                  style="background-color: violet; width: 50px"
                >
                  删除
                </el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页器 -->
      <el-pagination
        @size-change="getHasUser"
        @current-change="handler"
        v-model:current-page="pageNo"
        :page-sizes="[3, 5, 7, 9]"
        v-model:page-size="pageSize"
        layout=" prev, pager, next, jumper,->,sizes,total "
        :total="total"
      ></el-pagination>
      <!-- 测试按钮 -->
      <el-button
        type="primary"
        size="small"
        icon="User"
        style="background-color: violet; width: 80px"
        @click="setRole"
      >
        分配角色
      </el-button>
      <el-button
        @click="updateUser1"
        type="primary"
        size="small"
        icon="Edit"
        style="background-color: violet; width: 50px"
      >
        编辑
      </el-button>
      <el-popconfirm title="你确定要删除此用户信息吗？">
        <template #reference>
          <el-button
            type="primary"
            size="small"
            icon="Delete"
            style="background-color: violet; width: 50px"
          >
            删除
          </el-button>
        </template>
      </el-popconfirm>
    </el-card>
  </div>

  <!-- 抽屉结构，添加和修改用户时使用 -->
  <el-drawer
    title="我是标题"
    v-model="drawer"
    :direction="direction"
    :before-close="handleClose"
  >
    <template #header>
      <h1>{{ userParams.id ? '修改用户' : '添加用户' }}</h1>
    </template>
    <template #default>
      <el-form :model="userParams" :rules="rules" ref="formRef">
        <el-form-item label="用户姓名" style="margin: 20px 0" prop="username">
          <el-input
            placeholder="请输入用户的姓名"
            v-model="userParams.username"
          ></el-input>
        </el-form-item>
        <el-form-item label="用户昵称" style="margin: 20px 0" prop="name">
          <el-input
            placeholder="请输入用户的昵称"
            v-model="userParams.name"
          ></el-input>
        </el-form-item>
        <!-- 使用v-if控制显示与隐藏 -->
        <el-form-item
          v-if="!userParams.id"
          label="用户密码"
          style="margin: 20px 0"
          prop="password"
        >
          <el-input
            placeholder="请输入用户的密码"
            v-model="userParams.password"
          ></el-input>
        </el-form-item>
      </el-form>
    </template>
    <template #footer>
      <el-button @click="cancel">取消</el-button>
      <el-button
        type="primary"
        style="background-color: violet; width: 50px"
        @click="save"
      >
        确定
      </el-button>
    </template>
  </el-drawer>

  <!-- 抽屉结构2，分配用户的角色 -->
  <el-drawer
    title="我是标题"
    v-model="drawer1"
    :direction="direction"
    :before-close="handleClose"
  >
    <template #header>
      <h1>分配角色</h1>
    </template>
    <template #default>
      <el-form>
        <el-form-item label="用户姓名" style="margin: 20px 0">
          <el-input :disabled="true" v-model="userParams.username"></el-input>
        </el-form-item>
        <el-form-item label="职位列表" style="margin: 20px 0">
          <el-form>
            <el-form-item>
              <!-- 单个复选框 勾选情况由v-model的值决定 -->
              <el-checkbox
                :indeterminate="isIndeterminate"
                v-model="checkAll"
                @change="handleCheckAllChange"
              >
                全选
              </el-checkbox>
            </el-form-item>
            <el-form-item>
              <!-- 多个复选框 v-model用来收集已有的信息并勾选 -->
              <el-checkbox-group
                v-model="userRole"
                @change="handleCheckedCitiesChange"
              >
                <el-checkbox
                  v-for="(role, index) in allRole"
                  :label="role"
                  :key="index"
                  style="margin: 10px"
                >
                  {{ role.roleName }}
                </el-checkbox>
              </el-checkbox-group>
            </el-form-item>
          </el-form>
        </el-form-item>
      </el-form>
    </template>
    <template #footer>
      <el-button @click="drawer1 = false">取消</el-button>
      <el-button
        type="primary"
        style="background-color: violet; width: 50px"
        @click="confirmClick"
      >
        确定
      </el-button>
    </template>
  </el-drawer>
</template>

<script lang="ts" setup>
import {
  reqUserInfo,
  reqAddOrUpdateUser,
  reqAllRole,
  reqSetUserRole,
  reqRemoveUser,
  reqSelectUser,
} from '@/api/acl/user/index'
import type {
  AllRole,
  Records,
  RoleData,
  SetRoleData,
  User,
} from '@/api/acl/user/type'
import type { userResponseData } from '@/api/acl/user/type'
import { reqRemoveAttr } from '@/api/product/attr'
import { ElMessage } from 'element-plus'
import { ref, onMounted, reactive, nextTick } from 'vue'
//引人控制刷新的仓库
import useHomeSettingStore from '@/store/setting'
//使用仓库
const settingStore = useHomeSettingStore()
let pageNo = ref<number>(1)
let pageSize = ref<number>(7)
let total = ref<number>(10)
//添加与修改时控制抽屉的显示于隐藏
let drawer = ref<boolean>(false)
//分配角色时控制抽屉
let drawer1 = ref<boolean>(false)
//存储全部已有的用户账户信息
let userArr = ref<Records>([])
//存储全部职位的数据
let allRole = ref<AllRole>([])
//存储用户已有的职位数据
let userRole = ref<AllRole>([])
//收集新增或者修改的用户信息,且接口放回的数据是一个对象
//存储批量删除的id
let selecIdArr = ref<User[]>([])
//收集新增和修改的用户信息参数
let userParams = reactive<User>({
  username: '',
  name: '',
  password: '',
})
//获取form组件实例用于发送请求之前对整个表单进行校验
let formRef = ref()
//收集用户输入的关键字来进行搜索
let keyword = ref<string>('')
onMounted(() => {
  getHasUser()
})
//获取用户信息的方法
async function getHasUser(pager = 1) {
  //收集当前页码如没有pageNo,默认回到第一页
  pageNo.value = pager
  let result: any = (await reqUserInfo(
    pageNo.value,
    pageSize.value,
    keyword.value,
  )) as unknown as userResponseData
  if (result.code === 200) {
    total.value = result.data.total
    userArr.value = result.data.records
  }
}
//分页器改变时的触发事件回调
function handler() {
  //默认回到第一页
  getHasUser()
}
//添加用户方法回调
function addUser() {
  drawer.value = true
  //每次点击添加按钮显示抽屉都需要把上一次的数据清空包括id控制显示修改还是添加标题，使用Object.assign跟空值合并
  Object.assign(userParams, {
    username: '',
    name: '',
    password: '',
    id: 0,
  })
  //清除上一次表单的校验信息
  // nextTick()用于获取更新后的DOM，由于el-form隐藏在抽屉里，第一次显示抽屉拿不到表单的组件实例
  nextTick(() => {
    // clearValidate()清除某个字段的校验信息
    formRef.value.clearValidate('username')
    formRef.value.clearValidate('name')
    formRef.value.clearValidate('password')
  })
}
//编辑用户账号方法的回调
function updateUser(row: User) {
  drawer.value = true
  //点击编辑按钮时收集已有信息
  Object.assign(userParams, row)
  //再次点击编辑按钮清除上一次留下的信息
  Object.assign(userParams, {
    username: '',
    name: '',
    password: '',
  })
  //清除上一次表单的校验信息
  // nextTick()用于获取更新后的DOM，由于el-form隐藏在抽屉里，第一次显示抽屉拿不到表单的组件实例
  nextTick(() => {
    // clearValidate()清除某个字段的校验信息
    formRef.value.clearValidate('username')
    formRef.value.clearValidate('name')
  })
}
//测试编辑
function updateUser1(id = 1) {
  drawer.value = true
  userParams.id = id
  Object.assign(userParams, {
    username: '',
    name: '',
    password: '',
  })
  nextTick(() => {
    // clearValidate()清除某个字段的校验信息
    formRef.value.clearValidate('username')
    formRef.value.clearValidate('name')
    formRef.value.clearValidate('password')
  })
}
//添加或修改确定按钮的回调,发请求
async function save() {
  //点击保存按钮时，对整个表单校验通过才能发请求执行后续操作
  await formRef.value.validate()
  drawer.value = false
  let result = await reqAddOrUpdateUser(userParams)
  if (result.code === 200) {
    //关闭抽屉
    drawer.value = false
    ElMessage({
      type: 'success',
      message: userParams.id ? '修改成功' : '添加成功',
    })
    //获取最新的用户信息,修改留在当前页，更新回到第一页
    getHasUser(userParams.id ? pageNo.value : 1)
    //浏览器自动刷新一次，当修改到当前账户时需要手动刷新才能退出登录，但也会导致修改信息时也回到第一页
    window.location.reload()
  } else {
    ElMessage({
      type: 'error',
      message: userParams.id ? '修改失败' : '添加失败',
    })
  }
}
//取消按钮回调
function cancel() {
  drawer.value = false
  //清空数据
  Object.assign(userParams, {
    username: '',
    name: '',
    password: '',
  })
}
//表单校验的规则对象
const rules = {
  // 校验字段：用户名字
  username: [{ required: true, trigger: 'blur', validator: validatorUsername }],
  //用户昵称
  name: [{ required: true, trigger: 'blur', validator: validatorName }],
  //用户密码
  password: [{ required: true, trigger: 'blur', validator: validatorPassword }],
}
//username自定义校验规则函数(校验规则对象，表单元素文本内容，放行/错误信息提示函数)
function validatorUsername(_rule: any, value: any, callBack: any) {
  if (value.trim().length >= 5) {
    callBack()
  } else {
    callBack(new Error('用户名字至少五位'))
  }
}
//name自定义校验规则函数
function validatorName(_rule: any, value: any, callBack: any) {
  if (value.trim().length >= 5) {
    callBack()
  } else {
    callBack(new Error('用户昵称至少五位'))
  }
}
//password校验规则函数
function validatorPassword(_rule: any, value: any, callBack: any) {
  if (value.trim().length >= 6) {
    callBack()
  } else {
    callBack(new Error('用户密码至少六位'))
  }
}
//分配角色按钮的回调
async function setRole(row: User) {
  drawer1.value = true
  //合并数据，根据id将用户姓名呈现
  Object.assign(userParams, row)
  //发送请求获取全部职位以及用户已有的职位信息
  let result: any = await reqAllRole(userParams.id as number)
  if (result.code === 200) {
    //存储全部职位
    allRole.value = result.data.allRolesList
    //存储用户已有的职位
    userRole.value = result.data.assignRoles
    //获取信息成功显示抽屉
    drawer1.value = true
  }
}
//收集复选框的全选数据
const checkAll = ref<boolean>(false)
//用于显示全选框不确定的样式
let isIndeterminate = ref<boolean>(true)
//点击全选复选框触发事件的回调
function handleCheckAllChange(val: boolean) {
  // 每次点击全选框val会进行true/false的切换
  userRole.value = val ? allRole.value : []
  isIndeterminate.value = false
}
//职位复选框改变时触发的事件
function handleCheckedCitiesChange(value: string[]) {
  //value值可以收集已经勾选的复选框信息
  const checkedCount = value.length
  //全选框的状态,如果已经勾选内容的等于全部内容则全选为真
  checkAll.value = checkedCount === allRole.value.length
  //控制全选框的不确定样式
  isIndeterminate.value = !(checkedCount === allRole.value.length)
}
//分配职位确定按钮的回调
async function confirmClick() {
  drawer1.value = false
  //收集参数
  let data: SetRoleData = {
    userId: userParams.id as number,
    roleIdList: userRole.value.map((item) => {
      return item.id as number
    }),
  }
  //发请求分配职位
  let result: any = await reqSetUserRole(data)
  if (result.code === 200) {
    ElMessage({
      type: 'success',
      message: '分配职务成功',
    })
    drawer1.value = false
    //获取更新后的用户信息
    getHasUser(pageNo.value)
  }
}
//气泡确认框删除某一个用户的事件回调
async function deleteUser(userId: number) {
  let result: any = await reqRemoveUser(userId)
  if (result.code === 200) {
    ElMessage({
      type: 'success',
      message: '删除成功',
    })
    getHasUser(userArr.value.length > 1 ? pageNo.value : pageNo.value - 1)
  }
}
//table复选框勾选时会触发的事件,会自动收集选中用户的信息
function selectChange(value: any) {
  selecIdArr.value = value
}
//批量删除事件的回调
async function deleteSelectUser() {
  //收集请求所需参数
  let idList: any = selecIdArr.value.map((item) => {
    return item.id
  })
  let result: any = reqSelectUser(idList)
  if (result.code === 200) {
    ElMessage({
      type: 'success',
      message: '删除成功',
    })
    getHasUser(userArr.value.length > 1 ? pageNo.value : pageNo.value - 1)
  }
}
//搜索按钮的回调
async function search() {
  //根据关键字获取用户数据
  getHasUser()
  //清空关键字
  keyword.value = ''
}
//重置按钮的回调
function reset() {
  settingStore.Refresh = !settingStore.Refresh
}

// //测试复选框按钮是否全选
// let checkAll = ref<boolean>(false)
// let allRole = ref(['前台', '前端', '后厨', '后端', '测试', '炒菜'])
// //默认勾选已有的复选框
// let userRole = ref(['前端','后端'])
// //用于显示不确定的状态
// let isIndeterminate = ref<boolean>(true)
// //点击全选复选框触发事件的回调
// function handleCheckAllChange(val:boolean) {
//   // 每次点击全选框val会进行true/false的切换
//   userRole.value = val?allRole.value:[]
//   isIndeterminate.value = false
// }
// //职位复选框改变时触发的事件
// function handleCheckedCitiesChange(value:string[]) {
//     //value值可以收集已经勾选的复选框信息
//     const checkedCount = value.length
//     //全选框的状态,如果已经勾选内容的等于全部内容则全选为真
//     checkAll.value = checkedCount === allRole.value.length
//     //控制全选框的不确定样式
//     isIndeterminate.value = !(checkedCount === allRole.value.length)
// }
</script>

<style scoped lang="scss">
.user1 {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
</style>
